package Logica.Gestores;

import java.util.ArrayList;
import java.util.List;

import AccesoADatos.EquipoFantasiaDAO;
import AccesoADatos.FormacionDAO;
import Excepciones.FondosInsuficientesException;
import Excepciones.JugadorYaIncluidoException;
import Excepciones.LimiteJugadorPorEquipoException;
import Excepciones.LugarNoDisponibleException;
import Logica.Entidades.EquipoDeFantasia;
import Logica.Entidades.EquipoDePrimera;
import Logica.Entidades.Formacion;
import Logica.Entidades.Jugador;
import Logica.Entidades.Puntaje;
import Presentacion.Interfaz;
import Presentacion.Pantallas.PanelCrearEquipo;

public class GestorFormacion {

	private FormacionDAO formacionDAO;
	private Interfaz padre;

	public GestorFormacion(Interfaz i){
		super();
		padre = i;
		formacionDAO = new FormacionDAO();
	}
	
	public Formacion crearFormacion(){
		return new Formacion();
	}
	
	public void agregarJugador(Formacion formacionEquipo, Jugador j) throws FondosInsuficientesException, JugadorYaIncluidoException, LimiteJugadorPorEquipoException, LugarNoDisponibleException{
		GestorEquipoFantasia gef = padre.getGestorEquipoFantasia();
		GestorEquipoDePrimera gedp = padre.getGestorEquipoDePrimera();
		String posicion = j.getPosicion();

		List<Jugador> titulares = formacionEquipo.getTitulares();
		List<Jugador> suplentes = formacionEquipo.getSuplentes();
		List<Jugador> total = new ArrayList<Jugador>();
		total.addAll(titulares);
		total.addAll(suplentes);
		
		boolean hayLibre = consultarLugarLibre(titulares,posicion);
		
		//Revisamos si hay lugar en los titulares
		if(hayLibre){
			int cotizacion = j.getCotizacion();
			int presupuestoUtilizado = gef.getPresupuestoUtilizado();
			
			if(presupuestoUtilizado + cotizacion <= 50000000){
				EquipoDePrimera ep = gedp.buscarEquipoPrimera(j);
				
				int cuenta = contarJugadoresMismoEquipo(ep,total);
				
				if(cuenta < 3){
					boolean jugadorYaIncluido = verificarJugadorNoIncluido(j,total);			
					if(!jugadorYaIncluido){
						formacionEquipo.addTitular(j);
						gef.setPresupuestoUtilizado(presupuestoUtilizado + cotizacion);
						padre.getPce().setPresupuesto(gef.getPresupuestoUtilizado());
						padre.getPce().mostrarTitulares(formacionEquipo);
					}
					else throw new JugadorYaIncluidoException();
					
				} else throw new LimiteJugadorPorEquipoException();
				
			} else throw new FondosInsuficientesException();
			
			
		}
		//Revisamos si hay lugar en los suplentes
		else if(consultarLugarLibreSuplentes(suplentes,posicion)){
			int cotizacion = j.getCotizacion();
			int presupuestoUtilizado = gef.getPresupuestoUtilizado();
			
			if(presupuestoUtilizado + cotizacion <= 50000000){
				EquipoDePrimera ep = gedp.buscarEquipoPrimera(j);
				
				int cuenta = contarJugadoresMismoEquipo(ep,total);
				
				if(cuenta < 3){
					boolean jugadorYaIncluido = verificarJugadorNoIncluido(j,total);			
					if(!jugadorYaIncluido){
						formacionEquipo.addSuplente(j);
						gef.setPresupuestoUtilizado(presupuestoUtilizado + cotizacion);
						padre.getPce().setPresupuesto(gef.getPresupuestoUtilizado());
						padre.getPce().mostrarSuplentes(formacionEquipo);
					}
					else throw new JugadorYaIncluidoException();
					
				} else throw new LimiteJugadorPorEquipoException();
				
			} else throw new FondosInsuficientesException();
		}
		else throw new LugarNoDisponibleException();
		
	}
	
	public boolean consultarLugarLibre(List<Jugador> titulares, String posicion){
		int maxCuenta;
		int cuenta = 0;
		
		if(posicion.equals("ARQ"))
			maxCuenta = 1;
		else if(posicion.equals("DEF") || posicion.equals("VOL"))
			maxCuenta = 4;
		else
			maxCuenta = 2;
		
		for(Jugador j: titulares)
			if(j != null && j.getPosicion().equals(posicion))
				cuenta++;
		return !(maxCuenta == cuenta);
	}
	
	public boolean consultarLugarLibreSuplentes(List<Jugador> suplentes, String posicion){
		int maxCuenta = 1;
		int cuenta = 0;
		
		for(Jugador j: suplentes)
			if(j != null && j.getPosicion().equals(posicion))
				cuenta++;
		return !(maxCuenta == cuenta);
	}
	
	public int contarJugadoresMismoEquipo(EquipoDePrimera ep, List<Jugador> tit){
		GestorEquipoDePrimera gedp = padre.getGestorEquipoDePrimera();
		int cuenta = 0;
		for(Jugador j : tit){
			if(j != null){
			EquipoDePrimera e = gedp.buscarEquipoPrimera(j);
			if(e.getNombre().equals(ep.getNombre()))
				cuenta ++;
			}
		}
		return cuenta;
	}
	
	public boolean verificarJugadorNoIncluido(Jugador j, List<Jugador> titulares){
		boolean incluido = false;
		for(Jugador jug: titulares){
			if(jug != null && (jug.getId() == j.getId()))
				incluido = true;
		}
		return incluido;
	}
	
	public void cambiarTitularPorSuplente(Formacion f, Jugador jTitular,String pos){
		
		Jugador jSuplente = f.getSuplentePosicion(pos);
		f.removeTitular(jTitular);
		f.addTitular(jSuplente,pos);
		f.removeSuplente(jSuplente,pos);
		f.addSuplente(jTitular,pos);
		padre.getPce().mostrarTitulares(f);
		padre.getPce().mostrarSuplentes(f);
	}
	
	public String buscarPosicion(int row){
		
		if(row == 0)
			return "ARQ";
		else if(row >= 1 && row <= 4)
			return "DEF";
		else if(row >= 5 && row <= 8)
			return "VOL";
		else
			return "DEL";
	}
	
	public void quitarJugador(Formacion f, Jugador j){
		List<Jugador> tit = f.getTitulares();
		boolean encontrado = buscarJugador(tit,j);
		if(encontrado){
			f.removeTitular(j);
			padre.getPce().mostrarTitulares(f);
		}
		else{
			f.removeSuplente(j);
			padre.getPce().mostrarSuplentes(f);
		}
		GestorEquipoFantasia gef = padre.getGestorEquipoFantasia();
		int presupuesto = gef.getPresupuestoUtilizado() - j.getCotizacion();
		gef.setPresupuestoUtilizado(presupuesto);
		padre.getPce().setPresupuesto(presupuesto);
	}
	
	public boolean buscarJugador(List<Jugador> lista, Jugador jugador){
		boolean encontrado = false;
		for(Jugador j: lista)
			if(j != null && (j.getId() == jugador.getId())){
				encontrado = true;
				break;
			}
		return encontrado;
	}
	
	public void guardarFormacion(EquipoDeFantasia e){
		GestorFecha gf = padre.getGestorFecha();
		int numeroFechaActual = gf.getNroFechaActual();
		formacionDAO.guardarFormacion(e.getFormacionActual(),e.getNombre(),numeroFechaActual);
	}
	
	public Formacion buscarFormacion(EquipoDeFantasia e,int numeroFecha){
		
		List<List<String>> formacionDto = formacionDAO.buscarFormacion(e,numeroFecha);

		if(formacionDto.size() == 0)
			return null;
		else{
			int id = (new Integer(formacionDto.get(0).get(0))).intValue();
			int puntaje = (new Integer(formacionDto.get(0).get(1))).intValue();
			int trans = (new Integer(formacionDto.get(0).get(2))).intValue();
			Formacion f = new Formacion(id,puntaje,trans);
			
			GestorJugador gj = padre.getGestorJugador();
			
			List<Jugador> tit = gj.buscarTitulares(f);
			List<Jugador> sup = gj.buscarSuplentes(f);
			
			f.setTitulares(tit);
			f.setSuplentes(sup);
			
			return f;
		}
	}
	
	public Formacion obtenerFormacionActual(String nombreEquipoFantasia, int nroFecha){
			
		List<List<String>> formacionActualDto = formacionDAO.obtenerFormacionActual(nombreEquipoFantasia, nroFecha);
		Formacion fActual = null;
		if(formacionActualDto.size() > 0){
			Integer idFormacion = new Integer(formacionActualDto.get(0).get(0));
			fActual = new Formacion();
			
			GestorJugador gj = padre.getGestorJugador();
			List<Jugador> titulares = gj.obtenerJugadoresTitulares(idFormacion, nroFecha);
			for(int i = 0; i < 11 ; i++){
				Jugador titular = titulares.get(i);
				fActual.addTitular(titular);
			}
			List<Jugador> suplentes = gj.obtenerJugadoresSuplentes(idFormacion, nroFecha);
			for(int i = 0; i < 4 ; i++){
				Jugador suplente = suplentes.get(i);
				fActual.addSuplente(suplente);
			}
		}
		return fActual;
			
	}

	public int calcularPuntaje(int nroFecha, Formacion formacionActual) {
		int puntaje = 0;
		int puntos = 0;
		List<Jugador> titulares = formacionActual.getTitulares();
		
		for (int i = 0; i < titulares.size(); i++){
			Jugador titular = titulares.get(i);
			int JugoMasDe20 = titular.getJugoMasDe20(nroFecha);
			
			if(JugoMasDe20 != 0){
				Puntaje puntajeTitular = titular.getPuntajeXFecha(nroFecha);
				puntos = puntajeTitular.sumatoriaDePuntos();
			}
			else {
				String posicion = titular.getPosicion();
				Jugador suplente = formacionActual.getSuplentePosicion(posicion);
				Boolean puntajeYaCalculado = suplente.getPuntajeCalculado(nroFecha);
				if(puntajeYaCalculado){
					puntos = 0;
				}
				else {
					JugoMasDe20 = suplente.getJugoMasDe20(nroFecha);
					if(JugoMasDe20 != 0){
						Puntaje puntajeSuplente = suplente.getPuntajeXFecha(nroFecha);
						puntos = puntajeSuplente.sumatoriaDePuntos();
					}
					else {
						puntos = 0;
					}
				}
			}
			formacionActual.setPuntaje(puntos);
			}
			puntaje = formacionActual.getPuntaje();
			return puntaje;
	}

	public void clonarFormacionParaFechaSiguiente(Formacion formacion, String nombreEquipoFantasia, int nroFecha) {
		formacionDAO.clonarFormacionParaFechaSiguiente(formacion, nombreEquipoFantasia, nroFecha);
	}

	public void guardarPuntajeFormacion(String nombreEquipoFantasia,int nroFecha, int puntaje) {
		formacionDAO.guardarPuntajeFormacion(nombreEquipoFantasia,nroFecha,puntaje);	
	}
	
}

